extends Control

# ========== 自定义音频对象类 ==========
# 音频项类，包含音频文件和自定义间隔时间
class AudioItem:
	var tag :int=0
	# 音频文件路径
	var audio_path: String = ""
	# 该音频的播放间隔时间（秒）
	var custom_interval: float = 0.1
	
	func _init(audio_tag: int = 0,path: String = "", interval: float = 0.1) -> void:
		"""初始化音频项"""
		tag = audio_tag
		audio_path = path
		custom_interval = interval
	
	func get_info() -> String:
		"""获取音频项信息"""
		return "音频: %s, 间隔: %.2fs" % [audio_path, custom_interval]

# 音频播放器组件引用
@onready var audio_stream_player_2d: AudioStreamPlayer2D = $AudioStreamPlayer2D

# ========== 播放列表配置变量 ==========
# 存储所有音频项对象的数组
var audio_playlist: Array[AudioItem] = []

# 当前正在播放的音频索引（从0开始）
var current_index: int = 0

# 是否自动播放（true=启动后自动播放，false=需要手动调用播放方法）
var auto_play: bool = true

# 全局播放间隔时间（秒），当AudioItem没有自定义间隔时使用
var default_interval: float = 0.1

# ========== 播放回调函数 ==========
# 在每个音频开始播放时调用的回调函数（用户可以自定义）
var on_audio_start_callback: Callable = Callable()

# 在每个音频播放完成时调用的回调函数（用户可以自定义）
var on_audio_finished_callback: Callable = Callable()

# 设置音频开始播放时的回调函数
func set_on_audio_start_callback(callback: Callable) -> void:
	"""设置音频开始播放时的回调函数"""
	on_audio_start_callback = callback

# 设置音频播放完成时的回调函数
func set_on_audio_finished_callback(callback: Callable) -> void:
	"""设置音频播放完成时的回调函数"""
	on_audio_finished_callback = callback

# 执行音频开始播放回调
func _execute_audio_start_callback(audio_item: AudioItem, index: int) -> void:
	"""执行音频开始播放回调"""
	if on_audio_start_callback.is_valid():
		on_audio_start_callback.call(audio_item, index)

# 执行音频播放完成回调
func _execute_audio_finished_callback(audio_item: AudioItem, index: int) -> void:
	"""执行音频播放完成回调"""
	if on_audio_finished_callback.is_valid():
		on_audio_finished_callback.call(audio_item, index)

# 程序启动时自动执行
func _ready() -> void:
	# ========== 设置默认播放列表 ==========
	# 使用AudioItem对象创建播放列表，每个音频可以有不同的播放间隔
	
	# 创建音频项对象（Godot风格：先创建再设置属性）
	var item1 = AudioItem.new()
	item1.audio_path = "res://audio/1.ogg"
	item1.custom_interval = 0.2
	
	var item2 = AudioItem.new()
	item2.audio_path = "res://audio/2.ogg"
	item2.custom_interval = 0.1
	
	var item3 = AudioItem.new()
	item3.audio_path = "res://audio/3.ogg"
	item3.custom_interval = 0.3
	
	var item4 = AudioItem.new()
	item4.audio_path = "res://audio/4.ogg"
	item4.custom_interval = 0.05
	
	var item5 = AudioItem.new()
	item5.audio_path = "res://audio/5.ogg"
	item5.custom_interval = 0.15
	
	var item6 = AudioItem.new()
	item6.audio_path = "res://audio/6.ogg"
	item6.custom_interval = 0.25
	
	var item7 = AudioItem.new()
	item7.audio_path = "res://audio/ding.ogg"
	item7.custom_interval = 0.5
	
	var item8 = AudioItem.new()
	item8.audio_path = "res://audio/hit.ogg"
	item8.custom_interval = 0.1
	
	audio_playlist = [item1, item2, item3, item4, item5, item6, item7, item8]
	
	# 显示默认播放列表信息
	print("=== 默认播放列表 ===")
	for i in range(audio_playlist.size()):
		print("%d. %s" % [i+1, audio_playlist[i].get_info()])
	print("===================")
	
	# ========== 开始自动播放 ==========
	# 如果设置为自动播放，则程序启动后立即开始播放播放列表
	if auto_play:
		start_playlist()

# ========== 播放控制方法 ==========

# 启动播放列表播放（重置到第一个音频）
func start_playlist() -> void:
	"""开始播放播放列表"""
	# 重置播放索引到第一个音频
	current_index = 0
	
	# 开始播放第一个音频，然后依次播放后续音频
	await play_next()

# 播放列表的核心播放逻辑
func play_next() -> void:
	"""播放下一个音频"""
	
	# ========== 检查播放完成 ==========
	# 如果当前索引超出播放列表范围，说明所有音频都已播放完成
	if current_index >= audio_playlist.size():
		print("播放列表播放完成")
		return
	
	# ========== 获取当前音频项 ==========
	var current_audio_item: AudioItem = audio_playlist[current_index]
	print("播放音频: %s" % current_audio_item.get_info())
	
	# ========== 动态加载音频文件 ==========
	# 使用load()函数而不是preload()，因为路径是动态变量
	# preload()只能在编译时加载常量路径
	var audio_stream = load(current_audio_item.audio_path)
	
	if audio_stream:
		# ========== 播放音频开始回调 ==========
		# 在开始播放前执行用户自定义的回调函数
		_execute_audio_start_callback(current_audio_item, current_index)
		
		# ========== 播放音频 ==========
		# 设置要播放的音频流
		audio_stream_player_2d.stream = audio_stream
		
		# 开始播放音频
		audio_stream_player_2d.play()
		
		# ========== 等待音频播放完成 ==========
		# 使用await等待音频播放完成的信号
		# 这样可以确保上一个音频完全播放结束后再播放下一个
		await audio_stream_player_2d.finished
		
		# ========== 播放音频完成回调 ==========
		# 在音频播放完成后执行用户自定义的回调函数
		_execute_audio_finished_callback(current_audio_item, current_index)
		
		# ========== 添加自定义播放间隔 ==========
		# 使用该音频项的自定义间隔时间
		if current_audio_item.custom_interval > 0:
			await get_tree().create_timer(current_audio_item.custom_interval).timeout
		
		# ========== 播放下一个音频 ==========
		# 索引增加1，准备播放下一个音频
		current_index += 1
		await play_next()
	else:
		# ========== 处理音频加载失败 ==========
		# 如果音频文件加载失败，打印错误信息并继续播放下一个
		print("音频文件加载失败: ", current_audio_item.audio_path)
		current_index += 1
		await play_next()



# 设置完全自定义的播放列表
func set_custom_playlist(audio_items: Array[AudioItem]) -> void:
	"""设置自定义播放列表"""
	# ========== 停止当前播放 ==========
	# 如果有音频正在播放，立即停止
	if audio_stream_player_2d.playing:
		audio_stream_player_2d.stop()
		print("停止当前播放的音频")
	
	# 替换整个播放列表
	audio_playlist = audio_items
	
	# 重置播放索引到开始位置
	current_index = 0
	
	# 显示设置结果
	print("设置自定义播放列表，共", audio_playlist.size(), "个音频项")
	
	# 显示新播放列表信息
	print("=== 自定义播放列表 ===")
	for i in range(audio_playlist.size()):
		print("%d. %s" % [i+1, audio_playlist[i].get_info()])
	print("====================")
	
	# ========== 立即开始播放 ==========
	# 设置完成后立即开始播放新的播放列表
	# 不再依赖auto_play变量，直接启动播放
	await start_playlist()

# ========== 便利方法 ==========

# 快速创建单个音频项（Godot风格的便利方法）
func create_audio_item(audio_path: String, interval: float = -1) -> AudioItem:
	"""创建音频项"""
	var item = AudioItem.new()
	item.audio_path = audio_path
	
	# 如果间隔时间小于0，使用默认间隔
	var final_interval = interval
	if final_interval < 0:
		final_interval = default_interval
	item.custom_interval = final_interval
	
	return item

# 从字符串路径数组快速创建播放列表
func create_playlist_from_paths(file_paths: Array[String], intervals: Array[float] = []) -> Array[AudioItem]:
	"""从文件路径数组创建播放列表"""
	var result: Array[AudioItem] = []
	
	for i in range(file_paths.size()):
		var interval = default_interval
		# 如果提供了间隔数组且索引有效，使用对应的间隔
		if i < intervals.size():
			interval = intervals[i]
		result.append(create_audio_item(file_paths[i], interval))
	
	return result

# 创建带随机间隔的播放列表
func create_random_interval_playlist(file_paths: Array[String], min_interval: float = 0.05, max_interval: float = 0.5) -> Array[AudioItem]:
	"""创建带随机间隔的播放列表"""
	var result: Array[AudioItem] = []
	var rng = RandomNumberGenerator.new()
	rng.randomize()
	
	for path in file_paths:
		var random_interval = rng.randf_range(min_interval, max_interval)
		result.append(create_audio_item(path, random_interval))
	
	return result

# 显示播放列表信息
func show_playlist_info() -> void:
	"""显示当前播放列表信息"""
	print("=== 当前播放列表 ===")
	if audio_playlist.size() == 0:
		print("播放列表为空")
	else:
		for i in range(audio_playlist.size()):
			var marker = ""
			if i == current_index:
				marker = " <- 当前播放"
			print("%d. %s%s" % [i+1, audio_playlist[i].get_info(), marker])
	print("===================")

# ========== 演示方法 ==========

# 演示随机间隔播放列表
func demo_random_intervals() -> void:
	"""演示随机间隔播放效果"""
	var demo_paths = [
		"res://audio/1.ogg",
		"res://audio/2.ogg", 
		"res://audio/3.ogg",
		"res://audio/ding.ogg"
	]
	
	print("创建随机间隔播放列表...")
	var random_playlist = create_random_interval_playlist(demo_paths, 0.1, 0.8)
	set_custom_playlist(random_playlist)

# 演示自定义间隔播放列表
func demo_custom_intervals() -> void:
	"""演示自定义间隔播放效果"""
	var custom_playlist = [
		create_audio_item("res://audio/1.ogg", 0.1),    # 快速
		create_audio_item("res://audio/2.ogg", 0.3),    # 中等
		create_audio_item("res://audio/3.ogg", 0.6),    # 较慢
		create_audio_item("res://audio/ding.ogg", 1.0), # 很慢
		create_audio_item("res://audio/hit.ogg", 0.05)  # 很快
	]
	
	print("创建自定义间隔播放列表...")
	set_custom_playlist(custom_playlist)

# ========== 回调功能演示 ==========

# 音频开始播放时的处理函数
func on_audio_start_handler(audio_item: AudioItem, index: int) -> void:
	"""音频开始播放时的回调处理函数"""
	print("🎵 开始播放第%d个音频: %s" % [index + 1, audio_item.audio_path])
	
	# 这里可以添加自定义逻辑，比如：
	# - 更新UI显示当前播放的音频
	# - 触发视觉效果
	# - 记录播放日志
	# - 同步动画等

# 音频播放完成时的处理函数
func on_audio_finished_handler(audio_item: AudioItem, index: int) -> void:
	"""音频播放完成时的回调处理函数"""
	print("✅ 第%d个音频播放完成: %s" % [index + 1, audio_item.audio_path])
	
	# 这里可以添加自定义逻辑，比如：
	# - 更新播放进度
	# - 触发下一个动画
	# - 统计播放时长
	# - 切换UI状态等

# 演示如何使用回调功能
func demo_callbacks() -> void:
	"""演示回调功能的使用"""
	print("=== 演示播放列表回调功能 ===")
	
	# 设置回调函数
	set_on_audio_start_callback(Callable(self, "on_audio_start_handler"))
	set_on_audio_finished_callback(Callable(self, "on_audio_finished_handler"))
	
	# 创建演示播放列表
	var demo_playlist = [
		create_audio_item("res://audio/1.ogg", 0.2),
		create_audio_item("res://audio/hit.ogg", 0.1),
		create_audio_item("res://audio/ding.ogg", 0.3)
	]
	
	print("开始播放带有回调功能的播放列表...")
	set_custom_playlist(demo_playlist)

# 清除回调设置
func clear_callbacks() -> void:
	"""清除所有回调设置"""
	on_audio_start_callback = Callable()
	on_audio_finished_callback = Callable()
	print("已清除所有回调设置")

# 获取当前回调状态
func get_callback_status() -> Dictionary:
	"""获取当前回调设置状态"""
	return {
		"has_start_callback": on_audio_start_callback.is_valid(),
		"has_finished_callback": on_audio_finished_callback.is_valid()
	}
